<script lang="ts" setup>
import { ref } from 'vue';

import { CloudUploadOutlined as CloudUpload } from '@ant-design/icons-vue';
import { FolderOpen } from '@icon-park/vue-next';

interface Props {
  acceptedTypes?: string[]; // 接受的文件类型
  multiple?: boolean; // 是否支持多选
  disabled?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  acceptedTypes: undefined,
  multiple: true,
  disabled: false,
});

const emit = defineEmits<{
  error: [message: string];
  filesSelected: [files: File[]];
}>();

const fileInput = ref<HTMLInputElement>();
const isDragOver = ref(false);

// 验证文件
const validateFiles = (files: File[]): File[] => {
  const validFiles: File[] = [];

  for (const file of files) {
    // 检查文件类型
    if (props.acceptedTypes && props.acceptedTypes.length > 0) {
      const fileExt = file.name.split('.').pop()?.toLowerCase();
      const isTypeAccepted = props.acceptedTypes.some((type) => {
        if (type.startsWith('.')) {
          return type.toLowerCase() === `.${fileExt}`;
        }
        return file.type.includes(type) || type === '*';
      });

      if (!isTypeAccepted) {
        emit('error', `文件 "${file.name}" 类型不支持`);
        continue;
      }
    }

    validFiles.push(file);
  }

  return validFiles;
};

// 文件拖拽处理
const handleDragEnter = (e: DragEvent) => {
  e.preventDefault();
  e.stopPropagation();
  if (!props.disabled) {
    isDragOver.value = true;
  }
};

const handleDragOver = (e: DragEvent) => {
  e.preventDefault();
  e.stopPropagation();
};

const handleDragLeave = (e: DragEvent) => {
  e.preventDefault();
  e.stopPropagation();

  // 只有当离开整个拖放区域时才重置状态
  const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();
  const x = e.clientX;
  const y = e.clientY;

  if (x < rect.left || x > rect.right || y < rect.top || y > rect.bottom) {
    isDragOver.value = false;
  }
};

const handleDrop = (e: DragEvent) => {
  e.preventDefault();
  e.stopPropagation();
  isDragOver.value = false;

  if (props.disabled) return;

  const files = [...(e.dataTransfer?.files || [])];
  const validFiles = validateFiles(files);

  if (validFiles.length > 0) {
    emit('filesSelected', validFiles);
  }
};

// 文件选择处理
const handleFileSelect = (e: Event) => {
  const target = e.target as HTMLInputElement;
  const files = [...(target.files || [])];

  // 即使用户取消选择文件（files为空），也要阻止事件冒泡
  e.stopPropagation();

  const validFiles = validateFiles(files);

  if (validFiles.length > 0) {
    emit('filesSelected', validFiles);
  }

  // 清空input，允许选择相同文件
  if (target) {
    target.value = '';
  }
};

// 触发文件选择
const triggerFileSelect = (e?: Event) => {
  if (!props.disabled) {
    // 阻止事件冒泡到父级Dialog
    if (e) {
      e.stopPropagation();
    }
    fileInput.value?.click();
  }
};

// 获取接受类型的显示文本
const acceptedTypesText = () => {
  if (!props.acceptedTypes || props.acceptedTypes.length === 0) {
    return '支持所有文件类型';
  }

  if (props.acceptedTypes.includes('*')) {
    return '支持所有文件类型';
  }

  return `支持类型：${props.acceptedTypes.join(', ')}`;
};
</script>

<template>
  <div
    class="border-border bg-card hover:border-primary hover:bg-accent relative rounded-lg border-2 border-dashed p-8 text-center transition-all duration-200"
    :class="{
      'border-primary bg-accent': isDragOver && !disabled,
      'cursor-not-allowed opacity-50': disabled,
      'cursor-pointer': !disabled,
    }"
    @dragenter="handleDragEnter"
    @dragover="handleDragOver"
    @dragleave="handleDragLeave"
    @drop="handleDrop"
    @click="(e) => triggerFileSelect(e)"
  >
    <!-- 拖放状态覆盖层 -->
    <div
      v-if="isDragOver && !disabled"
      class="bg-primary/10 border-primary absolute inset-0 flex items-center justify-center rounded-lg border-2 border-dashed"
    >
      <div class="text-center">
        <div class="text-primary mb-2 text-4xl">
          <CloudUpload size="48" />
        </div>
        <p class="text-primary text-lg font-medium">松开鼠标上传文件</p>
      </div>
    </div>

    <!-- 默认内容 -->
    <div class="mx-auto max-w-sm">
      <div class="mb-4 flex justify-center text-4xl text-gray-400">
        <FolderOpen size="48" />
      </div>

      <h3 class="mb-2 text-lg font-medium">上传文件</h3>

      <p class="text-muted-foreground mb-4 text-sm">
        拖拽文件到此处或点击选择文件
        <span v-if="multiple">（支持多选）</span>
      </p>

      <Button
        appearance="primary"
        :disabled="disabled"
        @click.stop="(e) => triggerFileSelect(e)"
      >
        选择文件
      </Button>

      <!-- 文件限制信息 -->
      <div class="text-muted-foreground mt-4 space-y-1 text-xs">
        <p>{{ acceptedTypesText() }}</p>
      </div>

      <!-- 隐藏的文件输入框 -->
      <input
        ref="fileInput"
        type="file"
        :multiple="multiple"
        :accept="acceptedTypes?.join(',')"
        :disabled="disabled"
        class="sr-only"
        @change="handleFileSelect"
        @click.stop
      />
    </div>
  </div>
</template>
